/**
 * 
 */
package com.digidata.rest.testing.engine;

import java.io.File;

import junit.*;
import junit.framework.*;
import groovy.lang.GroovyObject;
import groovyx.net.http.*;
import groovyx.net.*;
import groovy.util.GroovyTestCase;
import groovy.util.GroovyTestSuite;
import groovy.util.slurpersupport.GPathResult;
import groovyx.net.*;
import com.digidata.util.Log
import com.digidata.ui.GroovyInterface
import com.digidata.ui.UserInterface


/**
 * RestTestEngine provides an executable context from which to run test cases
 * based in either GroovyTestCase or Junit. 
 * @author geoff.martin
 *
 */
public class RestTestEngine{

	/**
	 * The name or numberof the test to run
	 */
	private static String testToRun	

	/**
	 * The path on which to find the test files that contain the test(s)	
	 */
	private static String pathToTestFiles
	
	/**
	 * Defines the mode in which to run tests.  Ex. single, multiple, from file, gui, etc.
	 */
	private static def TESTMODE 
	
	public static void main(String[] args) {
		if(args == []){
			//args = ["-t", "--path", ".\\scripts\\", "test_1_Test"]
			args = ["-g"]
		}

		TestRunner testRunner
		List<String> testToRunList = ["test_1_Test", "test_2_Test", "test_7_Test", "test_8_Test"] 
		if(argsParser(args)){
			if(TESTMODE == 'GUI'){
				UserInterface ui = new UserInterface(".\\scripts\\")
				ui.createTestSelectionWindow()
			}
			else{
				//testRunner = new TestRunner(pathToTestFiles, testToRun)
				testRunner = new TestRunner(pathToTestFiles, testToRunList)
			}
		}
		else
			System.exit(3)		
		
		if(TESTMODE != 'GUI'){
			TestResult tr = new TestResult()
			
			if(testRunner.testResult.wasSuccessful()){
				Log.info("Test Passed.")
				Log.info("Exiting with status: 0")
				System.exit(0)
			}
			else{
				Log.info("Test Failed.")
				testRunner.testResult.errors().each{
					Log.info("Test inconclusive:")
					Log.info(it.dump())
					Log.info(it.toString())
					Log.info("Exiting with status: 1")
					System.exit(1)
				}
				testRunner.testResult.failures().each{
					Log.info("Test assertion failed")
					Log.info(it.dump())
					Log.info(it.toString())
					Log.info("Exiting with status: 2")
					System.exit(2)
				}
			}
		}	
	}
	
	/**
	 * Parse the command line args into a CliBuilder object which handles the usage and 
	 * other standard CLI functions. 
	 * @param args Arguments from the command line
	 * @return Returns boolean value representing if the arguments conformed to an expected 
	 * syntax 
	 */
	private static boolean argsParser(args){
		def cli = new CliBuilder(usage:'RestTestEngine.groovy -[h|S|t|g] [file] [--path <path>]', header:'options')
		cli.g(argName:'gui', longOpt:'gui', 'Open the user interface')
		cli.h(longOpt:'help', 'Show usage information')
		cli.S(argName:'Suite', longOpt:'Suite', 'Run multiple tests.')
		cli.t(argName:'test', longOpt:'test', 'The name or identifier of the test to be run')
		//cli.L(argName:'list', longOpt:'list', 'A list of test to be run as a suite')
		cli._(argName:'path', longOpt:'path', args:1,  'Specify the path to the files.  Over-rides the default. [optional]')
		
		if( args == null && args == []){
			println "No arguments provided."
			cli.usage()
			return false
		}
		
		OptionAccessor options = cli.parse(args)
		
		if(options == null){
			println "Missing required command-line arguments."
			cli.usage()
			return false
		}
		
		if(options.h){
			println "h option"
			cli.usage()
			return false
		}
		
		if(options.S && options.t){
			println "Please select either -S (Suite) or -t (single test) mode."
			cli.usage()
			return false
		}
		
		if(options.g){
			println "Opening GUI..."
			TESTMODE = "GUI"
			return true
		}
		
		if(options.S || options.t){
			assert options.t 
			
			if(options.path)
				pathToTestFiles = options.path
				
			if(options.arguments()[0] != null)
				testToRun = options.arguments()[0]
			else{
				println "Error, no test case of Suite file specified."
				cli.usage()
				return false
			}
			
			if(options.S){
				TESTMODE = 'suite'
				println "-S Suite option not yet implemented.  Only single test execution is supported in this version."
				cli.usage()
				return false
			}
			else if(options.t){
				TESTMODE = 'single'
				return true
			}
			else{
				println "Error, no test mode [-S|t] specified."
				cli.usage()
				return false
			}
		}
		return false
	}
}